feat: 2026.08 release - #140
Merged
Merged
Conversation
Switch ticket behavior to prefer per-panel configuration instead of global settings. Key changes: - Use panel.TicketNotificationChannel, panel.UseThreads, panel.TranscriptChannelId and panel-level ticket permissions (PanelTicketPermissions) throughout (open/close/claim/reopen/startticket/add/switchpanel/etc.) instead of relying on global Settings. - Update add/remove admin/support flows to apply permission edits across each panel's notification channel (deduplicating by channel). - Remove global thread/transcript setup commands and related global handling; admin debug permission checks now operate on panels directly. - Open command: add panel autocomplete, split logic to open with a selected panel, and export BuildFormModal for reuse by slash contexts. - Default behaviors: fallback ticket limit set to 5 when no per-panel limit, default welcome message and simplified naming when not configured. - Misc: avoid deleting archive-channel DB entry on channel delete, adjust listeners to use panel channels, and various import/usage updates to database/sentry/handlers. These changes consolidate configuration to the panel level and prepare for per-panel overrides of notification channels, threads, transcripts and permissions.
Delete the ticket limit setup command and remove related DB usage and UI references. Removed LimitSetupCommand (deleted limit.go) and removed it from the setup command children. Stop persisting the created category ID in auto setup (auto.go) and stop loading/using the ticket limit in the user stats command (statsuser.go) — the "Open Tickets" field now shows only the open count. This cleans up the code paths for the deprecated ticket limit feature.
Move and consolidate the setup command implementation into the settings package: rename bot/command/impl/settings/auto.go -> bot/command/impl/settings/setup.go (package changed to settings) and delete the old parent setup file. Replace AutoSetupCommand with a single SetupCommand, remove the Children property/parent command behavior, and remove the freePanelLimit constant. Update command registration and event caller imports/usages to reference settings.SetupCommand instead of settings/setup. Also apply small cleanup changes in Execute (ignore edit error), getColour, and minor formatting tweaks.
Signed-off-by: Ben <ben@tickets.bot>
Introduce a new .env.example providing a comprehensive environment configuration template for the project. It documents sections and variables for Worker, Discord, Bot, Database, Cache, Redis, Kafka, proxies, Archiver, Web proxy, Integrations, Experiments, Observability and emoji IDs, marking required fields and listing default values where applicable to help developers set up local or production environments.
Switch many ticket flows to respect per-panel configuration instead of global settings. Loads Panel records where applicable and use panel flags (StoreTranscripts, FeedbackEnabled, CloseConfirmation, SupportCanView, SupportCanType, UsersCanClose, OverflowEnabled/CategoryId, ThreadArchiveDuration, panel auto-close settings) to drive behavior. Key changes: - Button handlers (close, open survey, exit survey, edit close reason, rate) now consult panel settings and pass booleans to logic. - Logic updates: CloseTicket/OpenTicket/claim/sendCloseEmbed now use panel data (including overflow/category logic and thread archive duration). - EditGuildArchiveMessageIfExists and EditDMMessageIfExists signatures changed to accept storeTranscripts and feedbackEnabled instead of full settings. - Member leave auto-close now iterates open tickets and applies per-panel auto-close + exclusion checks. - Permission/claim utilities now derive SupportCanView/Type and UsersCanClose from panel settings and panel-specific ticket permissions. - Removed several now-unnecessary global settings loads (e.g. debug command) and updated callers. - Updated locale submodule reference. This makes ticket behavior configurable on a per-panel basis and centralizes panel-driven overrides across the codebase.
Remove the conditional that set threadArchiveDuration from panel.ThreadArchiveDuration and always use the default value (10080) when creating a private thread. This simplifies the OpenTicket flow in bot/logic/open.go by not relying on the panel-provided archive duration.
Replace the boolean DeleteMentions usage with the MentionBehaviour string. Update the panel settings modal to display the Mention Behaviour value and change the ticket open logic to delete ping messages only when MentionBehaviour == "delete". This aligns UI text and runtime checks with the new mention behaviour representation.
Remove a leftover "// TODO: Remove" comment in bot/logic/open.go inside the OpenTicket function. This is a minor cleanup with no functional changes.
Signed-off-by: Ben <ben@tickets.bot>
Signed-off-by: Ben <ben@tickets.bot>
Add in-memory caching for FormInput API options to reduce repeated external requests. A mutex-protected map stores options per API config and user with TTL based on CacheDurationSeconds; cache is checked before fetching and populated after a successful fetch. Also add a clone helper to avoid sharing slices. Introduce a new category update publisher (messagequeue/categoryupdate.go) that polls the CategoryUpdateQueue and produces RPC topic messages to update ticket channel categories (with configurable delay/interval). Wire the publisher into the worker startup in cmd/worker/main.go.
Move the announcement-channel check and remove the Sentry span around it. Replace the previous raw Member permissions check with permissionwrapper.HasPermissionsChannel to verify SendMessagesInThreads for the parent channel; this uses the worker/guild/user/channel context instead of relying on InteractionMetadata.Member.Permissions. Update the reply to include the channel ID when the permission check fails.
* feat: Kafka to Redis Signed-off-by: Ben <ben@tickets.bot> * Delete cmd/.DS_Store * Hardcode redis keys --------- Signed-off-by: Ben <ben@tickets.bot> Co-authored-by: biast12 <53872542+biast12@users.noreply.github.com>
Add a background refresh loop that fetches public integration owners from Discord and stores them in the user cache so authors resolve even without shared guilds. Wire the loop into the worker startup alongside the existing cache refresh jobs.
Changed from using separate message templates to dynamically composing the close request message. This allows better control over message structure, ensuring the accept/deny prompt stays at the bottom in Discord. The message now builds in order: intro, optional reason, optional close timestamp, then prompt.
Detect whether a modal interaction has a source message and route responses accordingly. Added a hasSourceMessage parameter to HandleModalInteraction and passed it from the HTTP listener after probing payload.Event. ModalContext now stores hasSourceMessage; Defer only ACKs when a source message exists, and ReplyWith chooses ResponseMessage vs ResponseEdit based on that flag. Also enabled DisableAutoDefer for the open ticket command to align defer semantics. Imported encoding/json (aliased) to probe the payload. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds admin buttons to resync whitelabel bots and re-create their slash commands from the whitelabel data view. Includes new button handlers, registration in the interaction manager, and a shared command payload builder for recreating commands.
Simplify the admin whitelabel data response by removing the hardcoded "## Whitelabel" text display and separator. The command now renders only the generated whitelabel content, avoiding redundant UI elements.
Refactor duplicate panel disabled/force-disabled checks into a new replyIfPanelUnavailable function. This reduces code duplication and enables the check in ValidatePanelAccess to reject form-backed panels on click rather than after the user fills the modal.
Only wrap ticket content in spoiler markup when the panel is unset or still allows mentions. This preserves the existing plain-content behavior for panels configured with `mention_behaviour=none`.
Add channel-based handoff between goroutines to ensure the welcome message is always sent after mentions/pings in ticket creation. This prevents message reordering when both are sent concurrently from separate goroutines.
Signed-off-by: Ben <ben@tickets.bot>
Extract duplicated unclaim logic into reusable logic.UnclaimTicket() and logic.ApplyClaim() functions. Add message queue listener to handle claim/unclaim operations asynchronously via claimrelay. Implement atomic claiming using TryClaim() with proper AlreadyClaimedError handling. Refactor ClaimTicket() to separate database claim from channel permission changes.
Transfer now overwrites the existing claim for the target user before applying the claim logic, so ticket ownership is reassigned instead of failing on an existing claim.
Update the whitelabel resync button handler to detect intents rejection errors from `ReapplyIntents` and reply with a clear red error message instead of falling back to generic error handling. Other errors still use `ctx.HandleError(err)`.
Signed-off-by: Ben <ben@tickets.bot>
Refactors form API option loading to build context-aware placeholders (user, guild, member, permission, locale, panel) and safely substitute them with URL/header/JSON escaping. Adds POST body template support with auto-generated default payloads, parallel option fetches, and a hashed cache key based on the fully substituted request to prevent cross-user cache leakage.
Signed-off-by: Ben Hall <ben@tickets.bot>
Update the `channel` welcome-message substitution to safely handle tickets without a channel ID. It now returns an empty string when `ticket.ChannelId` is nil, preventing nil pointer dereferences when rendering placeholders.
Refactors placeholder substitution to support a plain-text mode that skips markup-only placeholders for embed text fields. Custom embed building now applies the right substitution per field, truncates text fields to Discord embed limits using rune-safe truncation, and consistently resolves `%avatar_url%` with a default fallback when user data is missing or lookup fails.
Updated `adminrecache` to require a `guild_id` argument instead of falling back to the current guild. The command now parses a raw string argument directly and returns a user-facing error message when the ID is invalid. Command dispatch in `event/caller.go` was adjusted accordingly to enforce argument presence (`ErrArgumentNotFound`) and pass a non-pointer string value.
Signed-off-by: Ben Hall <ben@tickets.bot>
Signed-off-by: Ben Hall <ben@tickets.bot>
9 tasks
BenHall-1
pushed a commit
that referenced
this pull request
Aug 30, 2026
Awaiting Response Category has been fully broken since #140
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
2026.08 Release
Type of Change
Testing
Checklist